/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.ui.util;

import java.awt.Component;
import java.awt.Rectangle;
import java.beans.PropertyVetoException;

import javax.swing.JComponent;
import javax.swing.JInternalFrame;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;


import who.tmap.ui.JFrameThematicMap;
import who.tmap.util.MiscHelper;

public class ThematicMapTreeUIHelper {
	
	private static final String THEMATIC_MAP_NODE ="Thematic Map";    
	private static final String MAP_NODE ="Base Map";
	private static final String DATA_NODE ="Data";
	private static final String CARTOGRAPHIC_DISPLAY_NODE ="Cartographic Display";
	private static final String ANNOTATIONS_NODE ="Annotations";
	
	private JFrameThematicMap jFrameThematicMap;
	
	public ThematicMapTreeUIHelper( JFrameThematicMap jFrameThematicMap ) {
		this.jFrameThematicMap =jFrameThematicMap;
	}

	/**
	 * This method initializes jTree
	 * 
	 * @return javax.swing.JTree
	 */
	public javax.swing.JTree getJTree() {
		if(jFrameThematicMap.jTree == null) {
			DefaultMutableTreeNode top = new DefaultMutableTreeNode( new TMapTreeNode( THEMATIC_MAP_NODE, null, jFrameThematicMap.getJPopupMenuThematicMap() ) );
			DefaultMutableTreeNode baseMapTreeNode = new DefaultMutableTreeNode( new TMapTreeNode( MAP_NODE, jFrameThematicMap.jFrameMap, jFrameThematicMap.getJPopupMenuBaseMap() ) );
			DefaultMutableTreeNode dataTreeNode = new DefaultMutableTreeNode( new TMapTreeNode( DATA_NODE, jFrameThematicMap.jFrameData, jFrameThematicMap.getJPopupMenuData() ) );
			DefaultMutableTreeNode cartographicDisplayTreeNode = new DefaultMutableTreeNode( new TMapTreeNode( CARTOGRAPHIC_DISPLAY_NODE, jFrameThematicMap.jFrameCartographicDisplay, jFrameThematicMap.getJPopupMenuCartographicDisplay() ) );	
			DefaultMutableTreeNode annotationsTreeNode = new DefaultMutableTreeNode( new TMapTreeNode( ANNOTATIONS_NODE, jFrameThematicMap.jFrameAnnotations, jFrameThematicMap.getJPopupMenuAnnotations() ) );			
			
			top.add( baseMapTreeNode );
			top.add( dataTreeNode );
			top.add( cartographicDisplayTreeNode );			
			top.add( annotationsTreeNode );		

			jFrameThematicMap.jTree = new javax.swing.JTree(top);
			jFrameThematicMap.jTree.setCellRenderer(new TMapTreeNodeCellRenderer());
						
			jFrameThematicMap.jTree.addMouseListener(new java.awt.event.MouseAdapter() {   
				public void mouseClicked(java.awt.event.MouseEvent e) {    
					TreePath selPath = jFrameThematicMap.jTree.getPathForLocation(e.getX(), e.getY()); 
					
					if ( selPath != null ) {
						jFrameThematicMap.jTree.setSelectionPath( selPath );    						

						DefaultMutableTreeNode node = (DefaultMutableTreeNode)jFrameThematicMap.jTree.getLastSelectedPathComponent();
						
						if ( node != null && ( node.getUserObject() instanceof TMapTreeNode ) ) {
							TMapTreeNode userObject =(TMapTreeNode)node.getUserObject();
							
							if ( userObject != null ) {
								JInternalFrame frame =userObject.getFrame();
								
								if ( frame != null ) {
									try {
										frame.setSelected( true );
										if ( frame.isIcon() ) {
											frame.setIcon( false );
										}
									} catch (PropertyVetoException e1) {
										e1.printStackTrace();
									}
								}
							}
						}						
					}
				} 
				
				/**
				 * Works for Linux (at least)
				 */
				public void mousePressed(java.awt.event.MouseEvent e) {
					treePopUp( e );
				}
				
				/**
				 * Works for MS Windows (at least)
				 */
				public void mouseReleased(java.awt.event.MouseEvent e) {
					treePopUp( e );
				}
			});		
			
		}
		return jFrameThematicMap.jTree;
	}
	
	/**
	 * Used by jTree mousePressed & mouseReleased
	 * in order to be multi OS compatible
	 * @param e
	 */
	private void treePopUp(java.awt.event.MouseEvent e) {
		//if ( e.isPopupTrigger()) {
			TreePath selPath = getJTree().getPathForLocation(e.getX(), e.getY()); 
			
			if ( selPath != null ) {
				getJTree().setSelectionPath( selPath );    						

				DefaultMutableTreeNode node = (DefaultMutableTreeNode)getJTree().getLastSelectedPathComponent();
				
				Rectangle rect =getJTree().getPathBounds( selPath );
				TMapTreeNode userObject =(TMapTreeNode)node.getUserObject();
				JPopupMenu jPopupMenu =userObject.getPopUp();						

				if ( jPopupMenu != null ) {
					jPopupMenu.show( (JComponent)e.getSource(), e.getX(), (int)rect.getY() + (int)rect.height );////e.getY() );
				}
			}
		//}		
	}
	
	/**
	 * A private class to handle tree node info
	 * @author stl
	 *
	 */
	private class TMapTreeNode {

		private String label;
		private JInternalFrame frame =null;
		private JPopupMenu popUp =null;
		
		public TMapTreeNode( String label, JInternalFrame frame, JPopupMenu popUp ) {
			this.label =label;
			this.frame =frame;
			this.popUp =popUp;
		}
	
		public JInternalFrame getFrame() {
				return frame;
		}

		public JPopupMenu getPopUp() {
			return popUp;
		}
		
		public String getLabel() {
			return label;
		}
		
		public String toString() {
			return label;
		}

	}
	
	private class TMapTreeNodeCellRenderer extends DefaultTreeCellRenderer {
		
		private MiscHelper miscUIHelper =new MiscHelper();

	    public Component getTreeCellRendererComponent(
	                        JTree tree,
	                        Object value,
	                        boolean sel,
	                        boolean expanded,
	                        boolean leaf,
	                        int row,
	                        boolean hasFocus) {

	        super.getTreeCellRendererComponent(
	                        tree, value, sel,
	                        expanded, leaf, row,
	                        hasFocus);
	        
	        TMapTreeNode tmapTreeNode =(TMapTreeNode)((DefaultMutableTreeNode)value).getUserObject();
	        
	        if ( MAP_NODE.equals( tmapTreeNode.getLabel() ) ) {
	        	setIcon( miscUIHelper.getImageIcon( "ic_map2.gif" ) );
	        } else if ( DATA_NODE.equals( tmapTreeNode.getLabel() ) ) {
	        	setIcon( miscUIHelper.getImageIcon( "ic_attrib2.gif" ) );
	        } else if ( CARTOGRAPHIC_DISPLAY_NODE.equals( tmapTreeNode.getLabel() ) ) {
	        	setIcon( miscUIHelper.getImageIcon( "ic_display2.gif" ) );
	        } else if ( ANNOTATIONS_NODE.equals( tmapTreeNode.getLabel() ) ) {
	        	setIcon( miscUIHelper.getImageIcon( "ic_legende2.gif" ) );
	        } else if ( THEMATIC_MAP_NODE.equals( tmapTreeNode.getLabel() ) ) {
	        	setIcon( miscUIHelper.getImageIcon( "ic_tmapdesigner.gif" ) );//"ic_tmap.gif" ) );
	        }

	        return this;
	    }

	}	
	
	/**
	 * Update tree selection based on the selected internal frame 
	 *
	 */
	public void updateJTreeSelection() {
		JInternalFrame selectedFrame =jFrameThematicMap.getJDesktopPane().getSelectedFrame();
		MutableTreeNode rootNode =(MutableTreeNode)getJTree().getModel().getRoot();

		for( int ct =0; ct < rootNode.getChildCount(); ct++ ) {
			DefaultMutableTreeNode node =(DefaultMutableTreeNode)rootNode.getChildAt( ct );
			TMapTreeNode tmapTreeNode =(TMapTreeNode)node.getUserObject();
			
			if ( selectedFrame == tmapTreeNode.frame ) {
				// Works only because we have a simple tree
				getJTree().setSelectionRow( ct + 1 );
				break;
			}
			
		}
	}	
}
